﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 版权所有 (c) 2022 北京超维景生物科技有限公司 保留所有权利。
 * CLR版本：4.0.30319.42000
 * 文件名：Kernel
 * 
 * 创建者：huangyang
 * 电子邮箱：huangyang@tvscope.cn
 * 创建时间：2023/2/8 11:37:30
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImageK.Plugin.Frame;

namespace ImageK
{
    /// <summary>
    /// Runs ImageJ menu commands in a separate thread.
    /// </summary>
    public class Executer
    {
        private static String previousCommand;
        private static CommandListener listener;
        private static List<object> listeners = new List<object>();

        private String command;
        private Thread thread;
        private bool repeatingCommand;

		/** Create an Executer that runs the specified menu
	    command in a separate thread using the specified image,
	    or using the active image if 'imp' is null. */
		public Executer(string cmd, ImagePlus imp)
        {
            if (cmd.StartsWith("Repeat"))
            {
                command = previousCommand;
                IJ.setKeyUp(Keys.Shift);
                repeatingCommand = true;
            }
            else
            {
                command = cmd;
                if (!(cmd.Equals("Undo") || cmd.Equals("Close")))
                    previousCommand = cmd;
            }
            IJ.resetEscape();
			//todo:这里暂时不考虑启动一个新线程执行Command
            Run();
            //          thread = new Thread(Run)
            //          {
            //              Name = cmd
            //          };
            //          // thread.setPriority(Math.max(thread.getPriority() - 2, Thread.MIN_PRIORITY));
            // // if (imp != null)
            // //              WindowManager.setTempCurrentImage(thread, imp);
            //          thread.Start();
        }

        public void Run()
        {
			if (command == null)
				return;
			if (listeners.Count > 0) 
            {
                lock (listeners)
                {
					for (int i = 0; i < listeners.Count; i++)
                    {
                        CommandListener listener = (CommandListener)listeners[i];
                        command = listener.commandExecuting(command);
                        if (command == null) return;
                    }
				}
			}
			try
			{
				if (Recorder.OnRecord)
				{
					//todo:
					// Recorder.setCommand(command);
					// runCommand(command);
					// Recorder.saveCommand();
				}
                else
                {
                    runCommand(command);
				}
				int len = command.Length;
				if (len > 0 && command[len - 1] != ']')
					IJ.setKeyUp(IJ.ALL_KEYS);  // set keys up except for "<", ">", "+" and "-" shortcuts
			}
			catch (Exception e)
			{
				//todo:
				// IJ.ShowStatus("");
				// IJ.showProgress(1, 1);
				// ImagePlus imp = WindowManager.getCurrentImage();
				// if (imp != null) imp.unlock();
				// string msg = e.Message;
				// if (e instanceof OutOfMemoryError)
				//     IJ.outOfMemory(command);
			 //    else if (e instanceof RuntimeException && msg != null && msg.equals(Macro.MACRO_CANCELED))
				// ; //do nothing
			 //    else
				// {
				// 	CharArrayWriter caw = new CharArrayWriter();
				// 	PrintWriter pw = new PrintWriter(caw);
				// 	e.printStackTrace(pw);
				// 	String s = caw.toString();
				// 	if (IJ.isMacintosh())
				// 	{
				// 		if (s.indexOf("ThreadDeath") > 0)
				// 			return;
				// 		s = Tools.fixNewLines(s);
				// 	}
				// 	int w = 500, h = 340;
				// 	if (s.indexOf("UnsupportedClassVersionError") != -1)
				// 	{
				// 		if (s.indexOf("version 49.0") != -1)
				// 		{
				// 			s = e + "\n \nThis plugin requires Java 1.5 or later.";
				// 			w = 700; h = 150;
				// 		}
				// 		if (s.indexOf("version 50.0") != -1)
				// 		{
				// 			s = e + "\n \nThis plugin requires Java 1.6 or later.";
				// 			w = 700; h = 150;
				// 		}
				// 		if (s.indexOf("version 51.0") != -1)
				// 		{
				// 			s = e + "\n \nThis plugin requires Java 1.7 or later.";
				// 			w = 700; h = 150;
				// 		}
				// 		if (s.indexOf("version 52.0") != -1)
				// 		{
				// 			s = e + "\n \nThis plugin requires Java 1.8 or later.";
				// 			w = 700; h = 150;
				// 		}
				// 	}
				// 	if (IJ.getInstance() != null)
				// 	{
				// 		s = IJ.getInstance().getInfo() + "\n \n" + s;
				// 		new TextWindow("Exception", s, w, h);
				// 	}
				// 	else
				// 		IJ.log(s);
            }
			finally
			{
				if (thread != null)
					WindowManager.setTempCurrentImage(null);
			}
		}


		public void runCommand(string cmd)
		{
			Dictionary<string,object> table = Menus.getCommands();
			string? className = table.ContainsKey(cmd) ? (string)table[cmd]:null;
			if (className != null)
			{
				string arg = "";
				if (className.EndsWith("\")"))
				{
					// extract string argument (e.g. className("arg"))
					int argStart = className.LastIndexOf("(\"");
					if (argStart > 0)
                    {
                        var len = (className.Length - 2) - (argStart + 2);
						arg = className.Substring(argStart + 2, len);
						className = className.Substring(0, argStart);
					}
				}
				if (Prefs.nonBlockingFilterDialogs)
				{
					//todo:
					// we have the plugin class name, let us see whether it is allowed to run it
					// ImagePlus imp = WindowManager.getCurrentImage();
					// bool imageLocked = imp != null && imp.isLockedByAnotherThread();
					// if (imageLocked && !allowedWithLockedImage(className))
					// {
					// 	IJ.beep();
					// 	IJ.ShowStatus("\"" + cmd + "\" blocked because \"" + imp.getTitle() + "\" is locked");
					// 	return;
					// }
				}
				// run the plugin
				// if (IJ.shiftKeyDown() && className.StartsWith("ij.plugin.Macro_Runner") && !Menus.getShortcuts().ContainsKey("*" + cmd))
				if (IJ.shiftKeyDown() && className.StartsWith("ImageK.Plugin.Macro_Runner"))
					IJ.open(IJ.getDirectory("plugins") + arg);
				else
					IJ.runPlugIn(cmd, className, arg);
			}
			else
            {
				//todo:
			    // is command in the Plugins>Macros menu?
				// if (MacroInstaller.runMacroCommand(cmd))
				// 	return;
				// // is it in the Image>Lookup Tables menu?
				// if (loadLut(cmd))
				// 	return;
				// // is it in the File>Open Recent menu?
				// if (openRecent(cmd))
				// 	return;
				// // is it an example in Help>Examples menu?
				// if (IJ.getInstance() != null && !GraphicsEnvironment.isHeadless())
				// {
				// 	if (Editor.openExample(cmd))
				// 		return;
				// }
				// if ("Auto Threshold".equals(cmd) && (String)table.get("Auto Threshold...") != null)
				// 	runCommand("Auto Threshold...");
				// else if ("Enhance Local Contrast (CLAHE)".equals(cmd) && (String)table.get("CLAHE ") != null)
				// 	runCommand("CLAHE ");
				// else
				// {
				// 	if ("Table...".equals(cmd))
				// 		IJ.runPlugIn("ij.plugin.NewPlugin", "table");
				// 	else
				// 	{
				// 		if (repeatingCommand)
				// 			IJ.runMacro(previousCommand);
				// 		else
				// 		{
				// 			if (!extraCommand(cmd))
				// 				IJ.error("Unrecognized command: \"" + cmd + "\"");
				// 		}
				// 	}
				// }
			}
		}
	}
}
